package service

import (
	"gorm.io/gorm"
	"shop-bean/constant"
	"shop-bean/dto"
	"shop-bean/model"
	"shop-bean/request"
	"shop-common/library/loggerV2"
	"shop-common/library/variables"
	"shop-common/utils/pagehelper"
	"shop-common/utils/queryWrapper"
	"shop-common/utils/uploader"
	"shop-service/repository"
	"strings"
)

type ISystemStoreService interface {
	Create(request *request.SystemStoreRequest) error
	FindPage(request *pagehelper.SearchPageRequest) (*pagehelper.Record, error)
	FindStatistic() (*dto.SystemStoreStatisticDTO, error)
	Updates(request *request.SystemStoreRequest) error
	UpdateStatus(ids []uint, status uint8) error
	Delete(ids []uint) error
}

type SystemStoreService struct {
	db         *gorm.DB
	repository repository.ISystemStoreRepository
}

func NewSystemStoreService() ISystemStoreService {
	return &SystemStoreService{variables.GormDB(), repository.NewSystemStoreRepository()}
}

func (s *SystemStoreService) Create(request *request.SystemStoreRequest) error {
	err := s.repository.Create(s.db, &model.SystemStore{
		Name:            request.Name,
		Introduction:    request.Introduction,
		Phone:           request.Phone,
		ProvinceId:      request.ProvinceId,
		Province:        request.Province,
		CityId:          request.CityId,
		City:            request.City,
		AreaId:          request.AreaId,
		Area:            request.Area,
		DetailedAddress: request.DetailedAddress,
		Image:           request.Image.AttId,
		OblongImage:     request.OblongImage.AttId,
		Longitude:       request.Longitude,
		Latitude:        request.Latitude,
		DayTime:         strings.Join(request.DayTime, " - "),
		Status:          constant.GLOBAL_ENABLE,
	})

	if err != nil {
		loggerV2.Error(err)
		return err
	}

	return nil
}

func (s *SystemStoreService) FindPage(request *pagehelper.SearchPageRequest) (*pagehelper.Record, error) {
	paginator := pagehelper.New().
		SetOffset(&request).SetFilter([]string{"tss.id"}).
		Push(queryWrapper.Eq("tss.status", request.Status)).
		IsPush(request.Keyword != "", queryWrapper.Like("tss.name", request.Keyword)).
		SetOrder("tss.created_at desc").Paginator()

	count, err := s.repository.Count(s.db, paginator.Params)
	if err != nil {
		loggerV2.Error(err)
		return nil, err
	}

	if count == 0 {
		return paginator.Result(nil, count)
	}

	rows, err := s.repository.FindPage(s.db, paginator.Params)
	if err != nil {
		loggerV2.Error(err)
		return nil, err
	}

	var list = make([]*dto.SystemStoreDTO, 0, len(rows))
	for _, row := range rows {
		list = append(list, &dto.SystemStoreDTO{
			Id:              row.Id,
			Name:            row.Name,
			Introduction:    row.Introduction,
			Phone:           row.Phone,
			ProvinceId:      row.ProvinceId,
			Province:        row.Province,
			CityId:          row.CityId,
			City:            row.City,
			AreaId:          row.AreaId,
			Area:            row.Area,
			DetailedAddress: row.DetailedAddress,
			Longitude:       row.Longitude,
			Latitude:        row.Latitude,
			ValidTime:       row.ValidTime,
			DayTime:         row.DayTime,
			Status:          row.Status,
			Image: &dto.AttachmentDTO{
				AttId: row.AttId,
				Url:   strings.Join([]string{uploader.GetHostStatic(row.ImageType), row.AttDir, row.Path}, ""),
			},
			OblongImage: nil,
			ImageId:     row.Image,
			OblongId:    row.OblongImage,
		})
	}

	return paginator.Result(list, count)
}

func (s *SystemStoreService) FindStatistic() (*dto.SystemStoreStatisticDTO, error) {
	statisticList, err := s.repository.FindStatistic(s.db)
	if err != nil {
		loggerV2.Error(err)
		return nil, err
	}

	headerNum := &dto.SystemStoreStatisticDTO{}
	for _, statistic := range statisticList {
		if statistic.Status == constant.GLOBAL_LOGIC_RECYCLE {
			headerNum.RecycleCount = statistic.Total
		} else if statistic.Status == constant.GLOBAL_ENABLE {
			headerNum.ShowCount = statistic.Total
		} else if statistic.Status == constant.GLOBAL_DISABLE {
			headerNum.HideCount = statistic.Total
		}
	}

	return headerNum, nil
}

func (s *SystemStoreService) Updates(request *request.SystemStoreRequest) error {
	err := s.repository.Updates(s.db, &model.SystemStore{
		Id:              request.Id,
		Name:            request.Name,
		Introduction:    request.Introduction,
		Phone:           request.Phone,
		ProvinceId:      request.ProvinceId,
		Province:        request.Province,
		CityId:          request.CityId,
		City:            request.City,
		AreaId:          request.AreaId,
		Area:            request.Area,
		DetailedAddress: request.DetailedAddress,
		Image:           request.Image.AttId,
		OblongImage:     request.OblongImage.AttId,
		Longitude:       request.Longitude,
		Latitude:        request.Latitude,
		DayTime:         strings.Join(request.DayTime, " - "),
		Status:          request.Status,
	})
	if err != nil {
		loggerV2.Error(err)
		return err
	}
	return nil
}

func (s *SystemStoreService) UpdateStatus(ids []uint, status uint8) error {
	if err := s.repository.UpdateStatus(s.db, ids, status); err != nil {
		loggerV2.Error(err)
		return err
	}

	return nil
}

func (s *SystemStoreService) Delete(ids []uint) error {
	if err := s.repository.BatchDelete(s.db, ids); err != nil {
		loggerV2.Error(err)
		return err
	}

	return nil
}
